Release 10.1A: OpenEdge Development:
Progress Dynamics Basic Development


Updates through the SBO

The business logic of the SBO is additive. That is, you can keep basic logic affecting only one table in each individual SDO as now. If you must add validation or other logic at the level of the SBO, it will have access to the update temp-tables for all of its contained SDOs. This enables the SBO pre/post/begin/endTransactionValidate procedures to use the RowObjUpd temp-tables from the different SDOs, map them to meaningful local temp-table names, and write normal (static) Progress 4GL logic against those tables. As described earlier, you can give a logical name to each SDO you drop onto it. This is the ObjectName property, which is initialized to the simple filename of the SDO, without the extension. You can change this instance property as needed to give the SDO a distinctive name within this SBO.

This renaming might be necessary, for example, if the same SDO appears more than once in the tree, which occurs frequently in real-world applications. An Item SDO, for example, might need to be named Item in one instance and AlternateItem in another instance, if that is how it is used within the SBO.

This property is then attached to a reference to the SDO temp-table include file. For example, the Order/OrderLine SBO can use the default SDO ObjectNames that will result in AppBuilder code generation to name its update tables orderfullo and orderlinfullo.

Transaction logic in the SBO

The transaction logic is also parallel to and augments the logic of the SDO. The SBO defines an encompassing transaction within which the data from individual SDOs is committed to the database. As with SDOs, if the AutoCommit property is true (which will be the default if there is no Commit-Source), then each individual Save operation results in one set of changes being committed to the database.

Note: If the Save is against a SmartDataViewer that updates fields from multiple SDOs, then it is possible that a single Save operation could update more than one database record.

If the AutoCommit property is false (which is the default if there is a Commit-Source), then the SBO can accumulate multiple updates on the client to be sent back to the server together. This would be considered the norm for SBO usage, since SBOs are primarily intended for use in situations where rows from multiple different SDOs must be committed as part of the same transaction. The exception to this is where two or more records related on a one-to-one basis are updated through an SBO. In this case, you do not need the Commit operation, and you can set AutoCommit to TRUE. Each save request invokes submitRow in the appropriate SDO.

These changes are stored on the client until a commit occurs. When Commit is chosen, or if AutoCommit is TRUE, the following sequence of events takes place:

  1. The CommitTransaction procedure is run in the client SBO. This procedure collects all the RowObjUpd tables from any modified SDOs on the client and passes them to the server-side SBO. It runs serverCommitTransaction in the AppServer SBO, which in turn copies the tables to their respective SDOs.
  2. The server-side SBO executes code similar to the following block of pseudo-code. An error detected at any point results in the commit being rolled back and the error message being returned to the client, as shown in the following example:
  3. RUN preTransactionValidate IN THIS-PROCEDURE NO-ERROR. 
    FOR EACH SDO: 
      IF preTransactionValidate is defined for it THEN 
       RUN pushTableAndValidate in the SDO  
        (INPUT Pre, INPUT-OUTPUT hROUTable).  
    END. 
    SBO-TRANS:    
    DO TRANSACTION: 
       RUN beginTransactionValidate IN THIS-PROCEDURE NO-ERROR. 
       /* ServerCommit will run beginTransactionValidate 
         in each SDO, commit the changes, and run 
         endTransactionValidate in each SDO.  
         Any errors will undo the whole SBO-TRANS. */ 
       FOR EACH SDO: 
         ServerCommit(). 
       END. 
       RUN endTransactionValidate IN THIS-PROCEDURE NO-ERROR. 
    END.  /* END TRANSACTION */ 
    FOR EACH SDO: 
      IF postTransactionValidate is defined for it THEN 
       RUN pushTableAndValidate in the SDO  
        (INPUT Post, INPUT-OUTPUT hROUTable). 
    END. 
    RUN postTransactionValidate IN THIS-PROCEDURE NO-ERROR. 
    

The pushTableAndValidate procedure referenced in this code tells the SDO being called whether this is pre- or post-transaction validation, and passes the SDO’s RowObjUpd table to it. This runs pre/postTransactionValidate in the SDO, and then returns the TEMP-TABLE back to the SBO in case it has changed. When commit is executed in the SDO, SDO code suppresses running pre/postTransactionValidate in the SDO if it is inside an SBO. It is run at the proper time from the SBO (to allow all preTransactionValidates to happen together, followed by the transaction, followed by all postTransactionValidates).

The pre/begin/end/postTransactionValidate procedure names are the same as the standard validation procedure hooks supported for SDOs. The SBO logic extends the logic of the SDOs without introducing new naming conventions. The additional validation logic entry points that are available for use with the Progress Dynamics SDO’s logic procedure (createPreTransValidate, etc.) are not defined for SBOs.

This nested form allows maximum flexibility in the location of SBO logic and the coordination of that logic with SDO logic. The pushTableAndValidate procedure (implemented in data.i to allow it to use the static SDO temp-table as a parameter) assures that changes are automatically shared between the SBO and its SDOs. The cost of organizing the code in this way is not as great as it might seem at first. pushTableAndValidate will not be executed except where validation procedures exist in the individual SDOs. It is important to let you control the placement of logic at each stage (pre/begin/end/post), and also at the appropriate place within each stage. The SBO can add its own logic at the very beginning of all logic, at the beginning of the transaction, at the very end of the transaction, and at the very end of all the logic (after all the SDOs’ postTransactionValidate procedures). Or a given SBO could completely replace the serverCommitTransaction procedure if necessary to control the logic in a special way. (Note that this procedure is defined in sbo.i, to receive the RowObjUpd temp-tables into the SBO’s definition of them, so you cannot override it, only replace it.)

The most common form of business logic that spans SDOs, namely assigning key values to new records, is handled automatically by the SBO support code in the serverCommitTransaction procedure. If you are adding rows to both a parent and child SDO in the same transaction, then ForeignField values are retrieved from the parent record after it has been written to the database and assigned to each of the child records. This is similar to the way in which key values are assigned to new records added through an SDO with a Data-Source. The difference is that the supporting code in the SBO allows both parent and child records to be added in the same transaction. All newly assigned values will be passed back to the client for display, as with any other changes made on the server-side.


Copyright © 2005 Progress Software Corporation
www.progress.com
Voice: (781) 280-4000
Fax: (781) 280-4095